package services;

import java.util.Collection;
import java.util.Date;
import java.util.Random;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import repositories.EventRepository;
import domain.Administrator;
import domain.Event;
import domain.Participant;

@Service
@Transactional
public class EventService {

	// Managed repository -----------------------------------------------------

	@Autowired
	private EventRepository eventRepository;

	@Autowired
	private AdministratorService administratorService;

	@Autowired
	private ParticipantService participantService;

	// Constructors -----------------------------------------------------------

	public EventService() {
		super();
	}

	// Simple CRUD methods ----------------------------------------------------

	public Event create() {
		Administrator a = administratorService.findByPrincipal();
		Event e = new Event();
		e.setCreationMoment(new Date());
		e.setAdministrator(a);
		e.setReferenceNumber(getRandonCode(8));
		return e;
	}

	public void save(Event e) {
		Assert.notNull(e);
		Assert.isTrue(e.getAdministrator().equals(
				administratorService.findByPrincipal()));

			Assert.isTrue(e.getRegistrations().isEmpty());
		
		

		// Comprobar que el momento de comienzo sea posterior al momento de
		// creacion
		Assert.isTrue(e.getCreationMoment().before(e.getStartMoment()),
				"tried to save an event which it start moment is before it creation moment");
		Assert.isTrue(e.getStartMoment().before(e.getFinishMoment()),
				"tried to save an event which it finish moment is before it start moment");

		eventRepository.save(e);
	}
	
	public void saveRating(Event e) {
		Assert.notNull(e);
		Assert.isTrue(administratorService.findByPrincipal()!=null);

		eventRepository.save(e);
	}

	public void delete(Event e) {
		Assert.notNull(e);
		Assert.isTrue(e.getAdministrator().equals(
				administratorService.findByPrincipal()));
		Assert.isTrue(e.getRegistrations().isEmpty());
		eventRepository.delete(e);
	}

	public Event findOne(int id) {
		Event e = eventRepository.findOne(id);
		Assert.notNull(e.getRoutes());
		return e;
	}

	public Collection<Event> findAll() {
		return eventRepository.findAll();
	}

	// Other business methods -------------------------------------------------

	public Collection<Event> findEventsByAdministrator() {
		Administrator ad = administratorService.findByPrincipal();
		return eventRepository.findEventsByAdministrator(ad.getId());
	}

	public Collection<Event> findEventsByParticipant() {
		Participant pa = participantService.findByPrincipal();
		return eventRepository.findEventsByParticipant(pa.getId());
	}

	public Collection<Event> findFutureEvents() {
		return eventRepository.findFutureEvents();
	}

	public Collection<Event> findPastEvents() {
		return eventRepository.findPastEvents();
	}

	public Collection<Event> findOngoingEvents() {
		return eventRepository.findOngoingEvents();
	}

	public Collection<Event> findOngoingEventsByAdministrator() {
		Administrator a = administratorService.findByPrincipal();
		return eventRepository.findOngoingEventsByAdministrator(a.getId());
	}

	protected String getRandonCode(int longitud) {
		String cadenaAleatoria = "";
		long milis = new java.util.GregorianCalendar().getTimeInMillis();
		Random r = new Random(milis);
		int i = 0;
		while (i < longitud) {
			char c = (char) r.nextInt(255);
			if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')) {
				cadenaAleatoria += c;
				i++;
			}
		}
		return cadenaAleatoria;
	}

	// Form object related methods ------------------------------------------
	public Boolean itsHacked(Event event){
		Boolean res = true;
		
		if(event.getId()!=0){
		Event persistedOne = eventRepository.findOne(event.getId());
		if(event.getAdministrator()==null || persistedOne.getAdministrator().equals(event.getAdministrator())){
//			if(event.getRoutes()==null || persistedOne.getRoutes().equals(event.getRoutes())){
				if(event.getReferenceNumber()==null || persistedOne.getReferenceNumber().equals(persistedOne.getReferenceNumber())){
					if(event.getCreationMoment()==null || event.getCreationMoment().equals((Date)persistedOne.getCreationMoment())){
//						if(event.getRegistrations()==null || persistedOne.getRegistrations().equals(event.getRegistrations())){
							res = false;
//						}
//					}
				}
			}
		}
		}
		else{
			res=false;
		}
		
		
		return res;
	}
	
}
